package com.betty.cscams.util;

import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Objects;

public class FileUtil {

    private static final Logger log = LoggerFactory.getLogger(FileUtil.class);

    /**
     * @throws Exception
     * @Title: uploadFile
     * @Description: 真实上传文件
     * @param @param file 文件信息
     * @param @param 文件上传目录
     * @param @param fileName 文件名（带后缀名）
     * @return void 返回类型
     * @date 2017-4-20 日期
     * @throws
     */
    public static void uploadFile(MultipartFile file,String fileName) throws Exception {
        try {
            File localFile = new File(fileName);
            if (!localFile.exists()) {
                if (!localFile.getParentFile().exists()) {
                    localFile.getParentFile().mkdirs();
                }
            }
            file.transferTo(localFile);
        } catch (Exception e) {
            log.error("上传文件出现异常");
            throw e;
        }
    }

    /**
     * @param response
     *            响应
     * @param filePath
     *            文件相对路径.
     * @param fileName
     *            指定文件名称.
     * @throws IOException
     * @Description: 下载附件.
     * @Title: attachmentDownload
     */
    public static void download(String filePath, String fileName, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //首先根据文档在项目中的存储路径建立File对象，并获取文档的名称和后缀。判断浏览器类型，防止中文文件名出现乱码。
        File downfile = new File(filePath);
        String ext = fileName.substring(fileName.lastIndexOf(".") + 1);
        String agent = (String)request.getHeader("USER-AGENT"); //判断浏览器类型
        try {
            if(agent != null && agent.indexOf("Fireforx") != -1) {
                fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1");   //UTF-8编码，防止输出文件名乱码
            }
            else {
                fileName = URLEncoder.encode(fileName,"UTF-8");
            }
        } catch (UnsupportedEncodingException e){
            e.printStackTrace();

        }


        //初始化读入字节流和读出字节流，并设置响应response的输出属性。
        BufferedInputStream bis = null;
        OutputStream os = null;
        //response.reset();
        response.setCharacterEncoding("utf-8");
        if( "docx".equals(ext) || "doc".equals(ext)) {
            response.setHeader("content-Type", "application/msword");// word格式
        }else if("pdf".equals(ext)) {
            response.setHeader("content-Type", "application/pdf"); // pdf格式
        }else if("xls".equals(ext)) {
            response.setHeader("content-Type", "application/vnd.ms-excel"); // xls格式
        }else if("xlsx".equals(ext)) {
           response.setHeader("content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // xlsx格式
        }else {
            response.setHeader("content-Type", "application/octet-stream");
        }
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName.replace("+","%20"));



//接着调用inputStream和outputStream的read、write函数进行IO流读写操作。最后在写出操作完成后，一定要关闭输出流。
        try {
            bis = new BufferedInputStream(new FileInputStream(downfile));
            byte[] b = new byte[bis.available() + 1000];
            int i = 0;
            os = response.getOutputStream();   //直接下载导出
            while((i = bis.read(b)) != -1) {
                os.write(b, 0, i);
            }
            os.flush();
            os.close();
        } catch (IOException e) {
        }finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }


    /**
     * 删除目录及目录下的文件
     *
     * @param dir
     *            要删除的目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String dir) {
        // 如果dir不以文件分隔符结尾，自动添加文件分隔符
        if (!dir.endsWith(File.separator)) {
            dir = dir + File.separator;
        }
        File dirFile = new File(dir);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            log.info("删除目录失败：" + dir + "不存在！");
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        for (int i = 0; i < Objects.requireNonNull(files).length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = FileUtil.deleteFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }  else if (files[i].isDirectory()) {
                // 删除子目录
                flag = FileUtil.deleteDirectory(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        dirFile.delete();
        if (!flag) {
            log.info("删除目录失败！");
            return false;
        }
        return true;
    }

    public static boolean deleteDir(File dirFile) {
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
            return false;
        }
        boolean flag = true;
        // 删除文件夹中的所有文件包括子目录
        File[] files = dirFile.listFiles();
        for (int i = 0; i < Objects.requireNonNull(files).length; i++) {
            // 删除子文件
            if (files[i].isFile()) {
                flag = FileUtil.deleteFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }  else if (files[i].isDirectory()) {
                // 删除子目录
                flag = FileUtil.deleteDirectory(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        dirFile.delete();
        if (!flag) {
            log.info("删除目录失败！");
            return false;
        }
        return true;
    }

    /**
     * 删除单个文件
     *
     * @param fileName
     *            要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                log.info("删除单个文件" + fileName + "成功！");
                return true;
            } else {
                log.info("删除单个文件" + fileName + "失败！");
                return false;
            }
        } else {
            log.info("删除单个文件失败：" + fileName + "不存在！");
            return false;
        }
    }

    public static boolean isImg(String suffix){
        boolean flag = false;
        if(suffix.equalsIgnoreCase(".png") ||   suffix.equalsIgnoreCase(".jpg")  || suffix.equalsIgnoreCase(".jpeg")){
            flag = true;
        }
        return flag;
    }
}
